import 'package:flutter/material.dart';
import 'package:get/get.dart';

import '../../themes/appTheme.dart';

class NumberPagination extends StatefulWidget {
  const NumberPagination({
    Key? key,
    required this.onPageChanged,
    required this.pageTotal,
    this.threshold = 10,
    this.pageInit = 1,
    this.colorPrimary = Colors.black,
    this.colorSub = Colors.white,
    this.controlButton,
    this.iconToFirst,
    this.iconPrevious,
    this.iconNext,
    this.iconToLast,
    this.fontSize = 12,
    this.fontFamily,
  }) : super(key: key);

  //Trigger when page changed
  final Function(int) onPageChanged;

  //End of numbers.
  final int pageTotal;

  //Page number to be displayed first
  final int pageInit;

  //Numbers to show at once.
  final int threshold;

  //Color of numbers.
  final Color colorPrimary;

  //Color of background.
  final Color colorSub;

  //to First, to Previous, to next, to Last Button UI.
  final Widget? controlButton;

  //The icon of button to first.
  final Widget? iconToFirst;

  //The icon of button to previous.
  final Widget? iconPrevious;

  //The icon of button to next.
  final Widget? iconNext;

  //The icon of button to last.
  final Widget? iconToLast;

  //The size of numbers.
  final double fontSize;

  //The fontFamily of numbers.
  final String? fontFamily;

  @override
  NumberPaginationState createState() => NumberPaginationState();

  toInt() {}
}

class NumberPaginationState extends State<NumberPagination> {
  late int rangeStart;
  late int rangeEnd;
  late int currentPage;
  late final Widget iconToFirst;
  late final Widget iconPrevious;
  late final Widget iconNext;
  late final Widget iconToLast;

  final pageNumberController = TextEditingController();

  @override
  void initState() {
    this.currentPage = widget.pageInit;
    this.iconToFirst = widget.iconToFirst ?? Icon(Icons.first_page, size: 24.0);
    this.iconPrevious =
        widget.iconPrevious ?? Icon(Icons.keyboard_arrow_left, size: 24.0);
    this.iconNext =
        widget.iconNext ?? Icon(Icons.keyboard_arrow_right, size: 24.0);
    this.iconToLast = widget.iconToLast ?? Icon(Icons.last_page, size: 24.0);

    _rangeSet();

    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  Widget _defaultControlButton(Widget icon) {
    return AbsorbPointer(
      child: TextButton(
        style: ButtonStyle(
          elevation: MaterialStateProperty.all<double>(0.0),
          padding: MaterialStateProperty.all<EdgeInsets>(
            EdgeInsets.all(6.0),
          ),
          minimumSize: MaterialStateProperty.all(
            Size(18, 18),
          ),
          foregroundColor: Get.isDarkMode
              ? MaterialStateProperty.all(Theme.of(context).primaryColorDark)
              : MaterialStateProperty.all(
                  Theme.of(context).primaryColorDark.withOpacity(0.6),
                ),
          backgroundColor: Get.isDarkMode
              ? MaterialStateProperty.all(Theme.of(context).primaryColor)
              : MaterialStateProperty.all(
                  Colors.white.withOpacity(0.6),
                ),
        ),
        onPressed: () {},
        child: icon,
      ),
    );
  }

  void _changePage(int page) {
    if (page <= 0) page = 1;

    if (page > widget.pageTotal) page = widget.pageTotal;

    setState(() {
      currentPage = page;
      _rangeSet();
      widget.onPageChanged(currentPage);
    });
  }

  void _rangeSet() {
    rangeStart = currentPage % widget.threshold == 0
        ? currentPage - widget.threshold
        : (currentPage ~/ widget.threshold) * widget.threshold;

    rangeEnd = rangeStart + widget.threshold;
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.all(2.0),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          InkWell(
            onTap: () => _changePage(0),
            child: Stack(
              children: [
                if (widget.controlButton != null) ...[
                  widget.controlButton!,
                  iconToFirst
                ] else
                  _defaultControlButton(iconToFirst),
              ],
            ),
          ),
          SizedBox(
            width: 3.0,
          ),
          InkWell(
            onTap: () => _changePage(--currentPage),
            child: Stack(
              children: [
                if (widget.controlButton != null) ...[
                  widget.controlButton!,
                  iconPrevious
                ] else
                  _defaultControlButton(iconPrevious),
              ],
            ),
          ),
          SizedBox(
            width: 9.0,
          ),
          ...List.generate(
            rangeEnd <= widget.pageTotal
                ? widget.threshold
                : widget.pageTotal % widget.threshold,
            (index) => Flexible(
              child: InkWell(
                splashColor: Colors.transparent,
                highlightColor: Colors.transparent,
                onTap: () => _changePage(index + 1 + rangeStart),
                child: Container(
                  margin: const EdgeInsets.all(4),
                  padding:
                      const EdgeInsets.symmetric(vertical: 4, horizontal: 8),
                  decoration: BoxDecoration(
                    color: (currentPage - 1) % widget.threshold == index
                        //Active pagination background
                        ? Get.isDarkMode
                            ? AppTheme.colors.primaryLight
                            : Get.theme.primaryColorDark
                        //Inactive pagination background
                        : Get.isDarkMode
                            ? Get.theme.primaryColorLight.withOpacity(0.6)
                            : Colors.white.withOpacity(0.8),
                  ),
                  child: Text(
                    '${index + 1 + rangeStart}',
                    style: TextStyle(
                        fontWeight: FontWeight.bold,
                        fontSize: widget.fontSize,
                        fontFamily: widget.fontFamily,
                        //Active pagination forground
                        color: (currentPage - 1) % widget.threshold == index
                            ? Get.isDarkMode
                                ? Colors.black
                                : Get.theme.primaryColorLight
                            //Inactive pagination forground
                            : Colors.black),
                  ),
                ),
              ),
            ),
          ),
          SizedBox(
            width: 10,
          ),
          InkWell(
            onTap: () => _changePage(++currentPage),
            child: Stack(
              children: [
                if (widget.controlButton != null) ...[
                  widget.controlButton!,
                  iconNext
                ] else
                  _defaultControlButton(iconNext),
              ],
            ),
          ),
          SizedBox(
            width: 4,
          ),
          InkWell(
            onTap: () => _changePage(widget.pageTotal),
            child: Stack(
              children: [
                if (widget.controlButton != null) ...[
                  widget.controlButton!,
                  iconToLast
                ] else
                  _defaultControlButton(iconToLast),
              ],
            ),
          ),
          SizedBox(
            width: 9,
          ),
          SizedBox(
            width: 90,
            child: Text(
              "Total: ".tr + widget.pageTotal.toString(),
              style: TextStyle(
                  fontSize: 14.0,
                  color: Get.isDarkMode
                      ? Get.theme.primaryColorDark
                      : Colors.black),
            ),
          ),
          SizedBox(
            width: 9,
          ),
          Container(
            alignment: Alignment.topCenter,
            width: 60.0,
            height: 24.0,
            child: TextField(
              textAlign: TextAlign.center,
              controller: pageNumberController,
              decoration: InputDecoration(
                hintText: 'page',
                hintStyle: TextStyle(
                    fontSize: 12.0,
                    color: Get.isDarkMode
                        ? Get.theme.primaryColorLight
                        : Colors.black),
                border: OutlineInputBorder(),
              ),
            ),
          ),
          SizedBox(
            width: 8,
          ),
          InkWell(
            onTap: () => _changePage(int.parse(pageNumberController.text)),
            child: AbsorbPointer(
              child: TextButton(
                style: ButtonStyle(
                  elevation: MaterialStateProperty.all<double>(1.0),
                  padding: MaterialStateProperty.all<EdgeInsets>(
                      EdgeInsets.all(6.0)),
                  minimumSize: MaterialStateProperty.all(Size(32, 32)),
                  foregroundColor: Get.isDarkMode
                      ? MaterialStateProperty.all(Colors.black)
                      : MaterialStateProperty.all(
                          Theme.of(context).primaryColorLight),
                  backgroundColor: MaterialStateProperty.all(Get.isDarkMode
                      ? Colors.white
                      : Get.theme.primaryColorDark),
                ),
                onPressed: () {},
                child: Text("Go", style: TextStyle(fontSize: 12.0)),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
